# -*- coding: utf-8 -*-
# @Author	: changfeng
# @Date		: 2025/9/13 17:06
# @Last Modified by:   changfeng
# @Last Modified time: 2025/9/13 17:06
# Thanks for your comments!
import logging
import time
from typing import Optional, List

from bson import ObjectId
from pymongo import UpdateOne
from src.basedata.domain.po import PersonPO
from src.basedata.domain.repositories import PersonAbstractRepository
from src.basedata.infrastructure.client.mongodb.repository import MongoDBRepository
from src.basedata.infrastructure.client.redis.repository import RedisRepository
from src.basedata.infrastructure.utils import const

logger = logging.getLogger(__name__)


class MotorPersonRepository(PersonAbstractRepository, MongoDBRepository, RedisRepository):
    def __init__(self, session, redis_pool):
        MongoDBRepository.__init__(self, session, const.Person)
        RedisRepository.__init__(self, redis_pool)

    async def batch_save(self, data: List[PersonPO]):
        bulk_ops = []
        for po in data:
            # 条件：匹配 code
            filter_query = {"employee_number": po.employee_number, "app_id": po.app_id, "obsoleted": False}
            # 操作：存在则更新（$set 覆盖字段），不存在则新增
            update_value = po.dict(exclude_none=True)
            created_at = update_value.pop("created_at", None) or (time.time() * 1000)
            created_by = update_value.pop("created_by", None)
            update_value.pop("obsoleted", False)

            update_query = {
                "$set": update_value,
                "$setOnInsert": {"created_at": created_at, "created_by": created_by, "obsoleted": False},
            }
            # 添加 upsert 操作
            bulk_ops.append(UpdateOne(filter_query, update_query, upsert=True))
        if bulk_ops:
            await self.bulk_write(bulk_ops, ordered=False)

    async def save_data_to_redis(self, app_code: str, data: List[PersonPO]):
        pipeline = self._create_pipeline()
        for po in data:
            update_value = po.dict()
            update_value.pop("id", None)
            for k, v in update_value.items():
                if v is None or isinstance(v, bool) or not isinstance(v, (bytes, str, int, float)):
                    update_value[k] = ''

            try:
                if po.employee_number:
                    pipeline.hmset(f'sys:doctor:{app_code}:{po.employee_number}', update_value)
                else:
                    logger.warning(
                        f'load cache for sys doctor app_code:{app_code}, data:{update_value} no field employee_number')
                if po.his_code:
                    pipeline.hmset(f'sys:doctor2:{app_code}:{po.his_code}', update_value)
            except Exception as e:
                logger.warning(f'load cache for sys doctor app_code:{app_code}, data:{update_value} failed with err:{str(e)}')
        try:
            await pipeline.execute(raise_on_error=True)
        except Exception as e:
            logger.error(f"person save to cache failed with：{str(e)}")
